package com.tool.common.utils;

import cn.hutool.core.text.CharSequenceUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.tool.common.exception.SystemException;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @author: zhoubin
 */
@Slf4j
@UtilityClass
public class JsonUtil {

    /**
     * jackson主类
     */
    ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 未知属性报错
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 日期格式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }

    /**
     * 将对象转为json串.
     *
     * @param t 泛型对象
     * @param <T> 泛型
     * @return 返回json字符串
     * @throws JsonProcessingException 解析失败返回该异常
     */
    public <T> String toJsonStr(T t) {

        String result = null;
        try {
            result = objectMapper.writeValueAsString(t);
        } catch (JsonProcessingException e) {
            String errMsg = CharSequenceUtil.format("对象 {} 转json串失败", t);
            log.error(errMsg, e);
            throw new SystemException(errMsg, e);
        }
        return result;
    }

    /**
     * 将json串根据class类型转为对象.
     *
     * @param json json串
     * @param clz 需要转换的对象的class类型
     * @param <T> 泛型
     * @return 返回一个对象
     * @throws JsonProcessingException 解析失败返回该异常
     */
    public <T> T toObject(String json, Class<T> clz) {
        T result = null;
        try {
            result = objectMapper.readValue(json, clz);
        } catch (JsonProcessingException e) {
            String errMsg = CharSequenceUtil.format("json串 {} 转对象 {} 异常", json, clz.getName());
            log.error(errMsg, e);
            throw new SystemException(errMsg, e);
        }

        return result;
    }

    /**
     * 将json串根据class类型转为对象.
     *
     * @param json json串
     * @param clz 需要转换的对象的class类型
     * @param <T> 泛型
     * @return 返回一个对象
     * @throws JsonProcessingException 解析失败返回该异常
     */
    public <T> List<T> toObjList(String json, Class<T> clz) {
        List<T> result = null;
        try {
            result = objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, clz));
        } catch (JsonProcessingException e) {
            String errMsg = CharSequenceUtil.format("json串 {} 转对象 {} 异常", json, clz.getName());
            log.error(errMsg, e);
            throw new SystemException(errMsg, e);
        }

        return result;
    }
}
